﻿/**
 ******************************************************************************
 * @file    async_task.h
 * @author  LiaoQingfu, QQ 2167195649
 * @version V1.0.0
 * @date    2018-07-01
 * @brief   实现一个异步线程，调用者可以将一次性任务，一次定时任务，循环定时任务加入到线程执行.
 *          该版本为初始化，尚未做充分的测试.
 *          该版本可以改进的方向：（1）目前是使用了有锁队列，在thread_loop调用到priority_queue
 *                            的API时锁的切换较多，可以考虑使用无锁队列，在aysnc_task模块里面
 *                            自己对队列进行加锁；
 *                            （2）目前在thread_loop是使用usleep的方式进行休眠，后续可以考虑
 *                            使用条件唤醒的机制，以便在async_task_add的新任务被及时相应。
 * ******************************************************************************
 */
#ifndef ASYNCTASK_H
#define ASYNCTASK_H

#include <stdint.h>
#include <pthread.h>
#include <unistd.h>
#include "priority_queue.h"

/*
 * 任务类型
 */
typedef enum _task_type
{
    kOnceOffTask = 0,   // 一次即时任务，但如果队列里面有其他任务则也要等待
    kOnceTimerTask,     // 一次定时执行任务
    kLoopTimerTask,     // 循环定时执行任务，直到被调用者手动删除
}task_type_e;

// 任务函数指针
typedef void (* task_ptr_t) (void *userdata);

// 任务句柄
typedef void* task_handle_t;
// 异步线程句柄
typedef void* thread_handle_t;

/**
 * @brief 获取当前时间，单位为毫秒
 * @return 返回当前时间，单位为毫秒
 */
uint64_t get_now_time();

/**
 * @brief 初始化一个异步线程
 * @param timer_precision 线程调度任务的时间精度，单位为毫秒，当没有可以执行的任务时先休眠timer_precision毫秒再去检测任务队列
 * @return 返回操作异步线程的句柄
 */
thread_handle_t aysnc_task_init(int64_t timer_precision);

/**
 * @brief 释放异步线程，如果还有任务则销毁任务队列
 * @param thread_handle 操作异步线程的句柄
 */
void aysnc_task_deinit(thread_handle_t thread_handle);

/**
 * @brief 添加一个执行任务
 * @param thread_handle 操作异步线程的句柄
 * @param task_type     任务类型
 * @param interval_time 间隔时间
 * @param user_data     用户指针
 * @param task_func_ptr 任务函数
 * @return 返回任务句柄，用户可以根据该句柄删除任务
 */
task_handle_t async_task_add(thread_handle_t thread_handle,
                             task_type_e task_type,
                             uint64_t interval_time,
                             void *user_data,
                             task_ptr_t task_func_ptr
                             );



/**
 * @brief 删除一个任务
 * @param thread_handle     操作异步线程的句柄
 * @param task_handle       要删除任务的句柄
 */
void async_task_delete(thread_handle_t thread_handle, task_handle_t task_handle);

#endif // ASYNCTASK_H
